<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <title>文档</title>
  <link href="../css/semantic/semantic.min.css" rel="stylesheet">
  <link href="../css/markdown.css" rel="stylesheet">
  <link href="../css/wtxynavigation.css" rel="stylesheet">
  <script src="../js/jquery.min.js"></script>
  <script type="text/javascript" src="../js/include.js"></script>
  <style>
    body{padding-top:0;background:#f7f7f7}
    body>.ui.container{width:100%;padding:0}
    #project-title{background:#6e6e6e;width:100%;line-height:3.572rem;color:#fff;font-size:1.2rem}
    #project-title .title-wrap{font-weight:700;padding:0 12px;width:100%;max-width:1366px!important;min-width:900px;margin:0 auto}
    #project-title .left,#project-title right{display:inline-block}
    #project-title .right{float:right}
    #project-title .right .wiki-actions .menu{left:auto;right:0;margin-top:.4em!important}
    #wiki-preview-container{width:100%;max-width:1366px!important;min-width:900px;padding:0;border:1px solid #e3e9ed;border-top:0}
    #wiki-preview>.ui.segment{margin-top:0;padding:1rem;padding-left:0;border:0}
    .hover-places{display:inline-block}
    #page-detail{width:60%;margin:0 auto}
    #page-detail .title{font-weight:700;font-size:24px;padding:12px 0;border-bottom:1px solid #ccc}
    #page-detail .content{margin-top:15px}
    .content p{word-wrap:break-word}
    #wiki-parent,#wiki-title,#wikis{display:none}
    .ui.grid{padding:0!important}
    #ex-all{cursor:pointer;color:#537c8d}
  </style>
</head>
<body>
  <div class="ui container">
    <div id="project-title">
      <div class="title-wrap">
        <div class="left">
          <i class="icon eye"></i>
          文档预览:
          mianmSDK
        </div>
        <div class="right">
          Export by Gitee
        </div>
      </div>
    </div>

    <div class="ui container" id="wiki-preview-container">
      <div id="wiki-preview">
        <div class="ui segment">
          <div id="page-detail" class="markdown-body">
            <div class='title'>23.Runtime数据结构</div><div class='content'><h1>
<a id="240-runtime-结构" class="anchor" href="#240-runtime-%E7%BB%93%E6%9E%84"></a>24.0 Runtime 结构</h1>
<p><img src="images/runtime01.png" alt="runtime01">
<img src="images/runtimeAll.png" alt="runtimeAll"></p>
<h1>
<a id="241-runtime数据结构主要有哪些" class="anchor" href="#241-runtime%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%BB%E8%A6%81%E6%9C%89%E5%93%AA%E4%BA%9B"></a>24.1 Runtime数据结构主要有哪些?</h1>
<p><strong>关键词</strong>:</p>
<h2>
<a id="描述" class="anchor" href="#%E6%8F%8F%E8%BF%B0"></a>描述</h2>
<h3>
<a id="1" class="anchor" href="#1"></a>1.</h3>
<h1>
<a id="答" class="anchor" href="#%E7%AD%94"></a>答:</h1>
<ul>
<li><code>objc_object</code></li>
<li><code>objc_class</code></li>
<li>
<code>isa</code>指针</li>
<li><code>method_t</code></li>
</ul>
<h1>
<a id="242-runtime数据结构作用" class="anchor" href="#242-runtime%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BD%9C%E7%94%A8"></a>24.2 Runtime数据结构作用?</h1>
<h2>
<a id="1-objc_object" class="anchor" href="#1-objc_object"></a>1. objc_object</h2>
<h3>
<a id="简介" class="anchor" href="#%E7%AE%80%E4%BB%8B"></a>简介</h3>
<h4>
<a id="我们平常使用的对象都是id类型的-id类型的对应runtime中就是objc_object" class="anchor" href="#%E6%88%91%E4%BB%AC%E5%B9%B3%E5%B8%B8%E4%BD%BF%E7%94%A8%E7%9A%84%E5%AF%B9%E8%B1%A1%E9%83%BD%E6%98%AFid%E7%B1%BB%E5%9E%8B%E7%9A%84-id%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AF%B9%E5%BA%94runtime%E4%B8%AD%E5%B0%B1%E6%98%AFobjc_object"></a>我们平常使用的对象都是<code>id</code>类型的, <code>id</code>类型的对应<code>runtime</code>中就是<strong>objc_object</strong>
</h4>
<h3>
<a id="包含" class="anchor" href="#%E5%8C%85%E5%90%AB"></a>包含</h3>
<ul>
<li><code>isa_t</code></li>
<li>关于<code>isa</code>操作相关的方法
<ul>
<li>
<ol>
<li>比如说通过<code>objc_object</code>结构来获取它的<code>isa</code>所指向的类对象</li>
</ol>
</li>
<li>
<ol start="2">
<li>包括类对象的<code>isa</code>指针来获取元类对象</li>
</ol>
</li>
</ul>
</li>
<li>弱引用相关
<ul>
<li>
<ol>
<li>比如说标记一个对象它是否曾经有过<strong>弱引用指针</strong>
</li>
</ol>
</li>
</ul>
</li>
<li>关联对象相关
<ul>
<li>
<ol>
<li>比如这个对象我们为他设置一些<code>关联属性</code>,  那么关联属性的一些相关方法, 也体现在<code>objc_object</code>这个结构体当中</li>
</ol>
</li>
</ul>
</li>
<li>内存管理相关
<ul>
<li>
<ol>
<li>比如说我们在<strong>MRC</strong>下面的<code>retain</code>和<code>release</code>
</li>
</ol>
</li>
<li>
<ol start="2">
<li>包括<strong>ARC</strong>和<strong>MRC</strong>下面的<code>@autoreleasepool{}</code>
</li>
</ol>
</li>
<li>
<ol start="3">
<li>实际上上面的这些关于内存管理相关方法实现,都是封装在<code>objc_object</code>这个结构体当中</li>
</ol>
</li>
</ul>
</li>
</ul>
<h2>
<a id="2-objc_class" class="anchor" href="#2-objc_class"></a>2. objc_class</h2>
<h4>
<a id="oc里面的类class-对应的就是runtime里面的objc_class数据结构" class="anchor" href="#oc%E9%87%8C%E9%9D%A2%E7%9A%84%E7%B1%BBclass-%E5%AF%B9%E5%BA%94%E7%9A%84%E5%B0%B1%E6%98%AFruntime%E9%87%8C%E9%9D%A2%E7%9A%84objc_class%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84"></a><code>OC</code>里面的类(<code>Class</code>), 对应的就是<code>runtime</code>里面的<code>objc_class</code>数据结构</h4>
<h4>
<a id="objc_class-它继承自objc_object-惊喜不" class="anchor" href="#objc_class-%E5%AE%83%E7%BB%A7%E6%89%BF%E8%87%AAobjc_object-%E6%83%8A%E5%96%9C%E4%B8%8D"></a><code>objc_class</code> 它继承自<code>objc_object</code> (惊喜不~)</h4>
<h3>
<a id="23-class-objc_class是对象吗" class="anchor" href="#23-class-objc_class%E6%98%AF%E5%AF%B9%E8%B1%A1%E5%90%97"></a>2.3 Class (objc_class)是对象吗?</h3>
<h4>
<a id="它是对象-我们称之为类对象" class="anchor" href="#%E5%AE%83%E6%98%AF%E5%AF%B9%E8%B1%A1-%E6%88%91%E4%BB%AC%E7%A7%B0%E4%B9%8B%E4%B8%BA%E7%B1%BB%E5%AF%B9%E8%B1%A1"></a>它是对象, 我们称之为<strong>类对象</strong>
</h4>
<h3>
<a id="objc_class包含如下" class="anchor" href="#objc_class%E5%8C%85%E5%90%AB%E5%A6%82%E4%B8%8B"></a>objc_class包含如下</h3>
<ul>
<li>
<p><code>Class superClass;</code>: <code>superClass</code>指针</p>
<ul>
<li>如果是类对象, <code>superClass</code>指针指向<strong>父类对象</strong>, 也就是平常说的类与与父类</li>
</ul>
</li>
<li>
<p><code>cache_t cache;</code>: 方法缓存.  消息传递的时候会涉及</p>
</li>
<li>
<p><code>class_data_bits_t bits</code>: 一个类的变量,属性,方法,都在<code>bits</code>中</p>
</li>
</ul>
<h2>
<a id="3-isa指针" class="anchor" href="#3-isa%E6%8C%87%E9%92%88"></a>3. isa指针</h2>
<h4>
<a id="isa_t实际上是c中的共用体" class="anchor" href="#isa_t%E5%AE%9E%E9%99%85%E4%B8%8A%E6%98%AFc%E4%B8%AD%E7%9A%84%E5%85%B1%E7%94%A8%E4%BD%93"></a><code>isa_t</code>实际上是<code>C++</code>中的共用体</h4>
<h4>
<a id="64位架构-isa_t是64个0或者1" class="anchor" href="#64%E4%BD%8D%E6%9E%B6%E6%9E%84-isa_t%E6%98%AF64%E4%B8%AA0%E6%88%96%E8%80%851"></a>64位架构, <code>isa_t</code>是64个<code>0</code>或者<code>1</code>
</h4>
<h4>
<a id="32位架构-isa_t是32个0或者1" class="anchor" href="#32%E4%BD%8D%E6%9E%B6%E6%9E%84-isa_t%E6%98%AF32%E4%B8%AA0%E6%88%96%E8%80%851"></a>32位架构, <code>isa_t</code>是32个<code>0</code>或者<code>1</code>
</h4>
<h3>
<a id="31-isa指针分类" class="anchor" href="#31-isa%E6%8C%87%E9%92%88%E5%88%86%E7%B1%BB"></a>3.1 isa指针分类</h3>
<ol>
<li>指针型的<code>isa</code>
</li>
<li>非指针型的<code>isa</code>
</li>
</ol>
<h3>
<a id="311-指针型的isa" class="anchor" href="#311-%E6%8C%87%E9%92%88%E5%9E%8B%E7%9A%84isa"></a>3.1.1 指针型的<code>isa</code>
</h3>
<p>指针型的<code>isa</code>: 它64个<code>0</code>或者<code>1</code>这些内容都代表, <code>Class</code>的地址</p>
<h3>
<a id="312-非指针型的isa" class="anchor" href="#312-%E9%9D%9E%E6%8C%87%E9%92%88%E5%9E%8B%E7%9A%84isa"></a>3.1.2 非指针型的<code>isa</code>
</h3>
<p>非指针型的<code>isa</code>:  它64个<code>0</code>或者<code>1</code>这些内容中只有部分代表<code>Class</code>的地址</p>
<p>1字节(Byte)=8位(bit) [6]</p>
<p>1KB( Kilobyte，千字节)=1024B [6]</p>
<p>1MB( Megabyte，兆字节)=1024KB [6]</p>
<p>1GB( Gigabyte，吉字节，千兆)=1024MB [6]</p>
<p>1TB( Trillionbyte，万亿字节，太字节)=1024GB [6]</p>
<p>1PB( Petabyte，千万亿字节，拍字节)=1024TB [6]</p>
<p>1EB( Exabyte，百亿亿字节，艾字节)=1024PB [6]</p>
<p>1ZB(Zettabyte，十万亿亿字节，泽字节)=1024EB [6]</p>
<p>1YB( Yottabyte，一亿亿亿字节，尧字节)=1024ZB [6]</p>
<p>1BB( Brontobyte，千亿亿亿字节)=1024YB [6]</p>
<p>4G = 4 * 1024 MB = 4 * 1024 * 1024 KB =  4 * 1024 * 1024 * 1024 / 8</p>
<p>4G的运行内存,然后每个指针地址是8字节, 所以最多也只有<code>(1024 * 1024 * 512 * 2 * 4 / 8)</code>这么多个地址, 也就是29位地址,所以用64位都代表地址,明显浪费</p>
<h2>
<a id="4-isa的指向" class="anchor" href="#4-isa%E7%9A%84%E6%8C%87%E5%90%91"></a>4. isa的指向</h2>
<h3>
<a id="对象的isa指针-指向其类对象" class="anchor" href="#%E5%AF%B9%E8%B1%A1%E7%9A%84isa%E6%8C%87%E9%92%88-%E6%8C%87%E5%90%91%E5%85%B6%E7%B1%BB%E5%AF%B9%E8%B1%A1"></a>对象的isa指针, 指向其类对象</h3>
<p><strong>实例</strong> <code>--------&gt;</code><strong>Class</strong></p>
<h3>
<a id="类对象的isa指针-指向其元类对象" class="anchor" href="#%E7%B1%BB%E5%AF%B9%E8%B1%A1%E7%9A%84isa%E6%8C%87%E9%92%88-%E6%8C%87%E5%90%91%E5%85%B6%E5%85%83%E7%B1%BB%E5%AF%B9%E8%B1%A1"></a>类对象的isa指针, 指向其元类对象</h3>
<p><strong>Class</strong> <code>-------&gt;</code><strong>MetaClass</strong></p>
<h3>
<a id="方法查找方式" class="anchor" href="#%E6%96%B9%E6%B3%95%E6%9F%A5%E6%89%BE%E6%96%B9%E5%BC%8F"></a>方法查找方式?</h3>
<ul>
<li>调用<strong>实例方法</strong>, 我们是到<strong>类对象</strong>中查找</li>
<li>调用<strong>类方法</strong>, 我们是到<strong>元类对象</strong>中去查找</li>
</ul>
<h2>
<a id="5-cache_t" class="anchor" href="#5-cache_t"></a>5. cache_t</h2>
<h3>
<a id="cache_t简介" class="anchor" href="#cache_t%E7%AE%80%E4%BB%8B"></a>cache_t简介</h3>
<ul>
<li>
<p><code>cache_t</code>是<strong>快速</strong>查找方法执行函数的结构</p>
<ul>
<li>比如说调用一个方法的时候, 如果有一个缓存,就不用到它对应方法列表当中逐一遍历的查找, 方法的具体实现.可以提高调用的速度.</li>
</ul>
</li>
<li>
<p><code>cache_t</code>是可<strong>增量扩展</strong>的<strong>哈希表</strong>结构</p>
<ul>
<li>
<strong>增量扩展</strong>: 当我们这个结构存储的量在增大的过程中, 它也会增大内存空间, 来支持更多的缓存</li>
<li>
<strong>哈希表</strong>: 用哈希表来实现这个结构, 主要是为了查找效率</li>
</ul>
</li>
<li>
<p><code>cache_t</code>是<strong>局部性原理</strong>的最佳应用</p>
<ul>
<li>我们在调用方法的时候, 往往就那么几个方法, 这几个方法的频次是最高的.</li>
<li>把最高频次的方法放到缓存当中,下次的命中率就更高</li>
</ul>
</li>
</ul>
<h3>
<a id="cache_t数据结构说明" class="anchor" href="#cache_t%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E8%AF%B4%E6%98%8E"></a>cache_t数据结构说明</h3>
<ul>
<li>首先可以理解为它是由一个<strong>数组</strong>来实现的.</li>
<li>
<strong>数组</strong>当中每一个元素是<code>bucket_t</code>结构体</li>
<li>
<code>bucket_t</code>组成
<ul>
<li>
<code>key</code>: 方法选择器名称, 它对应<code>OC</code>的<strong>SEL @selector</strong>
</li>
<li>
<code>IMP</code>: 方法实现. 我们可以理解它为一个无类型的函数指针</li>
</ul>
</li>
</ul>
<p><img src="images/runtimeCacheT.png" alt="runtimeCacheT"></p>
<p>通过哈希查找算法, 来定位<code>key</code>所对应的 <code>bucket_t</code>位于数组中的哪个位置.定位到位置,就可以拿到函数的具体实现.</p>
<h2>
<a id="6-class_data_bits_t" class="anchor" href="#6-class_data_bits_t"></a>6. <code>class_data_bits_t</code>
</h2>
<ul>
<li>
<code>class_data_bits_t</code>是<code>objc_class</code>下的一个结构</li>
<li>
<code>class_data_bits_t</code> 是对 <code>class_rw_t</code>的封装</li>
<li>
<code>class_rw_t</code>代表了<strong>类</strong>相关的<strong>读写</strong>信息......<strong>rw</strong>代表读写
<ul>
<li>比如给类添加分类中方法属性协议都在这里</li>
</ul>
</li>
<li>
<code>class_rw_t</code>是对<code>class_ro_t</code>的封装, <strong>ro</strong>带表只读</li>
</ul>
<h2>
<a id="7-class_rw_t" class="anchor" href="#7-class_rw_t"></a>7. <code>class_rw_t</code>
</h2>
<p><img src="images/runtimeclassRWt.png" alt="runtimeclassRWt"></p>
<h2>
<a id="8-class_ro_t" class="anchor" href="#8-class_ro_t"></a>8. <code>class_ro_t</code>
</h2>
<p><img src="images/runtimeclassROt.png" alt="runtimeclassRWt"></p>
<h2>
<a id="9-method_t" class="anchor" href="#9-method_t"></a>9. method_t</h2>
<p><code>method_t</code>他是对函数四要素的一个封装抽象.</p>
<p>数四要素:</p>
<ol>
<li>函数名称</li>
<li>函数返回值</li>
<li>函数参数</li>
<li>函数体</li>
</ol>
<p><img src="images/runtimemethod.png" alt="runtimemethod"></p>
<h2>
<a id="91-type-encoding" class="anchor" href="#91-type-encoding"></a>9.1 Type Encoding</h2>
<ul>
<li><code>const char * types;</code></li>
</ul>
<p><img src="images/runtimemethod02.png" alt="runtimemethod02"></p></div>
          </div>
        </div>
      </div>
      </div>
  </div>
</body>
</html>